package com.alinesno.cloud.gateway.admin.proxy.http;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alinesno.cloud.common.facade.enums.HasStatusEnums;
import com.alinesno.cloud.common.facade.wrapper.RestWrapper;
import com.alinesno.cloud.gateway.admin.entity.GateRuleEntity;
import com.alinesno.cloud.gateway.admin.service.IGateRuleService;
import com.alinesno.cloud.gateway.admin.utils.ConstomOkHttpClient;
import com.alinesno.cloud.gateway.core.dispather.factory.HttpServiceFactory;

import cn.hutool.core.date.DateTime;

/**
 * Http反向代理请求
 * 
 * @author WeiXiaoJin
 * @since 2020年2月1日 下午19:45:08
 */
@Service("httpServiceProxy")
public class HttpServiceProxy implements HttpServiceFactory {

	private static final Logger log = LoggerFactory.getLogger(HttpServiceProxy.class);

	@Autowired
	private IGateRuleService ruleService;

	@Override
	public Object handler(String uniquePrefix, String model, String method, HttpServletRequest frontEndReq, HttpServletResponse frontEndResp , Map<String, Object> params) {

		log.debug("unique prefix = {}", uniquePrefix);

		Assert.hasLength(uniquePrefix, "路由前缀不能为空.");
		Optional<GateRuleEntity> opt = ruleService.findOne(RestWrapper.create().eq("uniquePrefix", uniquePrefix).toSpecification());

		Assert.notNull(opt.isPresent(), "路由【" + uniquePrefix + "】未定义");
		GateRuleEntity rule = opt.get() ; 
		
		boolean isAllow = filterSession(rule , frontEndReq) ; 
		log.debug("is allow = {}", isAllow);
		
		// >>>>>>>>>>>>>>>>>>> 反向代理 >>>>>>>>>>>>>>>>>>>>
		String forwardUrl = rule.getForwardUrl() + frontEndReq.getRequestURI() ; 
	 
		ConstomOkHttpClient client = ConstomOkHttpClient.getInstance() ; 
		try {
			client.post(forwardUrl, params) ;
		} catch (IOException e1) {
			e1.printStackTrace();
		} 

		return null;
	}
	

	/**
	 * 过滤会话
	 * 
	 * @param session
	 * @param e
	 * @return
	 */
	private boolean filterSession(GateRuleEntity e , HttpServletRequest frontEndReq) {

		Assert.isTrue(e.getHasStatus() != HasStatusEnums.LEGAL.value , "服务未已关闭.") ; // 是否打开接口

		// >>>>>>>>>>>>>>>> 判断是否达到运行时间_start >>>>>>>>>>>>>>>>>>>
		long now = DateTime.now().getTime();
		Date endTime = e.getOpenTime();
		if (endTime != null) {
			Assert.isTrue(DateTime.of(endTime).getTime() - now < 0 , "服务已关闭时间.") ; 
		}

		Date startTime = e.getCloseTime();
		if (startTime != null) {
			Assert.isTrue(DateTime.of(startTime).getTime() - now > 0 , "服务未到开放时间.") ; 
		}
		// >>>>>>>>>>>>>>>> 判断是否达到运行时间_end >>>>>>>>>>>>>>>>>>>

		String clientIP = frontEndReq.getRemoteHost() ;  // 判断IP
		String accessIp = e.getAccessIp(); // 允许的IP(以,作为分隔符)
		if (StringUtils.isNoneBlank(accessIp)) {
			Assert.isTrue(accessIp.contains(clientIP) , "IP未在服务范围内.") ; 
		}

		String denyIp = e.getDenyIp(); // 限制IP(以,作为分隔符)
		if (StringUtils.isNoneBlank(denyIp)) {
			Assert.isTrue(denyIp.contains(clientIP) , "IP已被禁止.")  ; 
		}

//		int limitRequest = e.getLimitRequest(); // 限流(-1表示不限流)
//		String authType = e.getAuthType(); // 认证方式
//		int retrics = e.getRetrics(); // 重试次数(默认为1次)

		return true ;
	}

}
